import base64
import json
import os
import cv2
import requests
from django.http import HttpResponse
from datasource.camera import CameraFactory, BaseCamera
from datasource.minio_config import minioClient
from django.http import StreamingHttpResponse, Http404, JsonResponse
from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile

# 全局图像
globalimg = None
path = f'./cv_platform/media/f/'
def op_container(request):
    json_str = request.body
    json_dict = json.loads(json_str)  # 将原始数据转成字典格式
    fn = json_dict.get("fn", "默认值")  # 算子
    url = json_dict.get("url", "默认值")  # 图片地址
    params = json_dict.get("params", "默认值")  # 算子参数
    pic_url = './cv_platform/' + url
    print(pic_url)
    localimg = cv2.imread(pic_url)  # 读取图像供locals()使用
    localimg_gray = cv2.imread(pic_url,0)  # 读取图像供locals()使用
    print(params)
    try:
        exec(fn)
        codebase64 = base64.b64encode(cv2.imencode('.jpg', globalimg)[1]).decode()
        return JsonResponse({"data": {'data': codebase64}, "msg": '处理成功', 'code': 2000})
    except Exception as ex:
        print(ex.args)
        return JsonResponse({"data": {'data': 0}, "msg": ex.args, 'err': 4000})
def savescreenshots(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode('utf-8'))
        # 获取 base64 编码的图片数据
        image_data = data['src']
        dir = data['dir']
        os.makedirs(f'./cv_platform/media/screenshots/{dir}/', exist_ok=True)
        k = 0
        for i in data['src']:
            k= k +1
            image_data = i.split(',', 1)[1]
            # 解码图片数据
            image_data = base64.b64decode(image_data)
            with open(f'./cv_platform/media/screenshots/{dir}/{data["name"]}{k}.jpg', 'wb') as f:
                # 将图片数据写入文件
                f.write(image_data)
        return HttpResponse('Success')
    else:
        return HttpResponse('Invalid request')
def savepicture(request):
    if request.method == 'POST':
        f = request.FILES['file']
        bucketName = request.POST.get("bucketName")
        path = f'./cv_platform/media/screenshots/test/'
        os.makedirs(path, exist_ok=True)
        if isinstance(f, InMemoryUploadedFile):
            file_content = f.read()
        elif isinstance(f, TemporaryUploadedFile):
            file_path = f.temporary_file_path()
            with open(file_path, 'rb') as file:
                file_content = file.read()
        else:
            raise ValueError('Unsupported file type')
        file_name = f.name
        file_path = os.path.join(path, file_name)
        with open(file_path, 'wb') as file:
            file.write(file_content) 
        minioClient.fput_object(bucketName,file_name , file_path)
    return HttpResponse('Success')
localimg = None
def gen_display(camera,op=[],screenparams={'screentype':0,'interval':1,'total':100}):
    c = 1
    r = 0
    if screenparams['screentype'] == 0:
        while camera.cam.isOpened():
            globals()['localimg'] = camera.get_frame()
            if (c % screenparams['interval'] == 0):
                if r == screenparams['total']:
                    camera.flag = True
                    camera.cam.release()
                    camera.flag = False
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                for o in op:
                    params = o['parameters']
                    # print(params)
                    exec (o['content'])
                ret,globals()['localimg']  = cv2.imencode('.jpeg', globals()['localimg'])
                # cv2.imwrite(path + str(c) + '.jpg', frame)
                if ret:
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globals()['localimg'].tobytes() + b'\r\n')
            c += 1
    if screenparams['screentype'] == 1:
        while camera.cam.isOpened():
            # 读取图片
            globals()['localimg'] = camera.get_frame()
            FPS = camera.cam.get(5)
            frameRate = int(FPS) * screenparams['interval']
            if (c % frameRate == 0):
                if (r == screenparams['total']):
                    camera.cam.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                for o in op:
                    params = o['parameters']
                    print(params)
                    exec(o['content'])
                ret, globals()['localimg'] = cv2.imencode('.jpeg', globals()['localimg'])
                if ret:
                    # 转换为byte类型的，存储在迭代器中
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globals()['localimg'].tobytes() + b'\r\n')
            c += 1
def video(request):
    if request.method == 'GET':
        data = request.request_data
        screenparams = json.loads(data['params'])
        rtsp = screenparams['url']
        op = json.loads(data['op'])
        print(screenparams)
        try:
            # camera: BaseCamera = CameraFactory.get_camera(0,0)
            camera = BaseCamera(0)
            print(camera.cam.isOpened())
            return  StreamingHttpResponse(gen_display(camera,op,screenparams), content_type='multipart/x-mixed-replace; boundary=frame')
        except Exception:
            raise Http404

def getChatGptResponse(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode('utf-8'))
        res = requests.get(url='https://v1.apigpt.cn/',
                           params={"q": data['a']})
        answer =json.loads(res.text)
        print(answer)
        return JsonResponse({"data": {'data': answer['ChatGPT_Answer']}, "msg": answer['msg'], 'code': 2000})

def gen_display_camera(camera, screenparams={'screentype':1,'interval':1,'total':10}):
    """
    视频流生成器功能。
    """
    c = 1
    r = 0
    if screenparams['screentype'] == 0:
        while camera.isOpened():
            ret, frame = camera.read()
            if (c % screenparams['interval'] == 0):
                if r == screenparams['total']:
                    # camera.flag = True
                    camera.release()
                    # camera.flag = False
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                # cv2.imwrite(path + str(c) + '.jpg', frame)
                if ret:
                    yield frame
            c += 1
    if screenparams['screentype'] == 1:
        while camera.isOpened():
            # 读取图片
            ret, frame = camera.read()
            FPS = camera.get(5)
            frameRate = int(FPS) * screenparams['interval']
            if (c % frameRate == 0):
                if (r == screenparams['total']):
                    camera.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                if ret:
                    # 转换为byte类型的，存储在迭代器中
                    yield frame
            c += 1

import time
import docker
from ai.models import Models
import base64
import json
import os
import cv2
import requests
from django.http import HttpResponse

from ai.utils.config import docker_path
from ai.utils.docker_util import create_container, check_container, stop_container
from datasource.camera import CameraFactory, BaseCamera
from datasource.minio_config import minioClient
from django.http import StreamingHttpResponse, Http404, JsonResponse
from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile

# 全局图像
globalimg = None
path = f'./cv_platform/media/f/'


def op_container(request):
    json_str = request.body
    json_dict = json.loads(json_str)  # 将原始数据转成字典格式
    fn = json_dict.get("fn", "默认值")  # 算子
    url = json_dict.get("url", "默认值")  # 图片地址
    params = json_dict.get("params", "默认值")  # 算子参数
    pic_url = './cv_platform/' + url
    print(pic_url)
    localimg = cv2.imread(pic_url)  # 读取图像供locals()使用
    localimg_gray = cv2.imread(pic_url, 0)  # 读取图像供locals()使用
    print(params)
    try:
        exec(fn)
        codebase64 = base64.b64encode(cv2.imencode('.jpg', globalimg)[1]).decode()
        return JsonResponse({"data": {'data': codebase64}, "msg": '处理成功', 'code': 2000})
    except Exception as ex:
        print(ex.args)
        return JsonResponse({"data": {'data': 0}, "msg": ex.args, 'err': 4000})


def savescreenshots(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode('utf-8'))
        # 获取 base64 编码的图片数据
        image_data = data['src']
        dir = data['dir']
        os.makedirs(f'./cv_platform/media/screenshots/{dir}/', exist_ok=True)
        k = 0
        for i in data['src']:
            k = k + 1
            image_data = i.split(',', 1)[1]
            # 解码图片数据
            image_data = base64.b64decode(image_data)
            with open(f'./cv_platform/media/screenshots/{dir}/{data["name"]}{k}.jpg',
                      'wb') as f:
                # 将图片数据写入文件
                f.write(image_data)
        return HttpResponse('Success')
    else:
        return HttpResponse('Invalid request')


def savepicture(request):
    if request.method == 'POST':
        f = request.FILES['file']
        bucketName = request.POST.get("bucketName")
        path = f'./cv_platform/media/screenshots/test/'
        os.makedirs(path, exist_ok=True)
        if isinstance(f, InMemoryUploadedFile):
            file_content = f.read()
        elif isinstance(f, TemporaryUploadedFile):
            file_path = f.temporary_file_path()
            with open(file_path, 'rb') as file:
                file_content = file.read()
        else:
            raise ValueError('Unsupported file type')
        file_name = f.name
        file_path = os.path.join(path, file_name)
        with open(file_path, 'wb') as file:
            file.write(file_content)
        minioClient.fput_object(bucketName, file_name, file_path)
    return HttpResponse('Success')


localimg = None


def stop(request):
    if request.method == 'GET':
        data = request.request_data
        print(data)
        print(data['params'])
        screenparams = json.loads(data['params'])
        op = json.loads(data['op'])
        print(screenparams)
        print(op)
        # 关闭相机

        # 关闭容器
        stop_container()
        return JsonResponse({'code': 2000})


def ai_display(camera, op, screenparams):
    id = op
    model = Models.objects.get(pk=id)

    # 判断是否需要开启容器
    if not check_container():
        create_container()
        time.sleep(5)

    test_result_path = 'runs/' + model.name + '/test'  # 测试结果路径
    data_path = test_result_path + '/test.jpg'  # 测试图片路径
    model_type = model.type
    model_weights = model.weights
    # 访问
    url = 'http://127.0.0.1:8088/'
    params = {
        'model_type': model_type,
        'data_path': data_path,
        'test_result_path': test_result_path,
        'model_weights': model_weights
    }

    c = 1
    r = 0
    if screenparams['screentype'] == 0:
        while camera.cam.isOpened():
            # 读取图片
            globals()['localimg'] = camera.get_frame()
            if (c % screenparams['interval'] == 0):
                if r == screenparams['total']:
                    camera.cam.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                img = globals()['localimg']
                picture_path = os.path.join(docker_path, test_result_path, 'test.jpg')
                cv2.imwrite(picture_path, img)
                res = requests.get(url=url, params=params)
                print("time: " + res.text)
                globals()['localimg'] = cv2.imread(os.path.join(docker_path, test_result_path, 'exp', 'test.jpg'))
                ret, globals()['localimg'] = cv2.imencode('.jpeg', globals()['localimg'])
                if ret:
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globals()['localimg'].tobytes() + b'\r\n')
            c += 1
    if screenparams['screentype'] == 1:
        while camera.cam.isOpened():
            # 读取图片
            globals()['localimg'] = camera.get_frame()
            FPS = camera.get(5)
            frameRate = int(FPS) * screenparams['interval']
            if (c % frameRate == 0):
                if (r == screenparams['total']):
                    camera.cam.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                img = globals()['localimg']
                picture_path = os.path.join(docker_path, test_result_path, 'test.jpg')
                cv2.imwrite(picture_path, img)
                res = requests.get(url=url, params=params)
                print("time: " + res.text)
                globals()['localimg'] = cv2.imread(os.path.join(docker_path, test_result_path, 'exp', 'test.jpg'))
                ret, globals()['localimg'] = cv2.imencode('.jpeg', globals()['localimg'])
                if ret:
                    # 转换为byte类型的，存储在迭代器中
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globalimg.tobytes() + b'\r\n')
            c += 1


def gen_display(camera, op=[], screenparams={'screentype': 0, 'interval': 1, 'total': 100}):
    c = 1
    r = 0
    if screenparams['screentype'] == 0:
        while camera.cam.isOpened():
            globals()['localimg'] = camera.get_frame()
            if (c % screenparams['interval'] == 0):
                if r == screenparams['total']:
                    camera.flag = True
                    camera.cam.release()
                    camera.flag = False
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                for o in op:
                    params = o['parameters']
                    # print(params)
                    exec(o['content'])
                ret, globals()['localimg'] = cv2.imencode('.jpeg', globals()['localimg'])
                # cv2.imwrite(path + str(c) + '.jpg', frame)
                if ret:
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globals()['localimg'].tobytes() + b'\r\n')
            c += 1
    if screenparams['screentype'] == 1:
        while camera.cam.isOpened():
            # 读取图片
            globals()['localimg'] = camera.get_frame()
            FPS = camera.cam.get(5)
            frameRate = int(FPS) * screenparams['interval']
            if (c % frameRate == 0):
                if (r == screenparams['total']):
                    camera.cam.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                for o in op:
                    params = o['parameters']
                    print(params)
                    exec(o['content'])
                ret, globals()['localimg'] = cv2.imencode('.jpeg', globals()['localimg'])
                if ret:
                    # 转换为byte类型的，存储在迭代器中
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + globals()['localimg'].tobytes() + b'\r\n')
            c += 1


def video(request):
    if request.method == 'GET':
        data = request.request_data
        screenparams = json.loads(data['params'])
        rtsp = screenparams['url']
        op = json.loads(data['op'])
        print(screenparams)
        print(op)

        try:
            camera = cv2.VideoCapture(0)
            # camera: BaseCamera = CameraFactory.get_camera(0,0)
            camera = BaseCamera(0)
            print(camera.cam.isOpened())
            if type(op) == int:
                response = StreamingHttpResponse(ai_display(camera, op, screenparams),
                                                 content_type='multipart/x-mixed-replace; boundary=frame')
            else:
                print(op[0]['content'])
                response = StreamingHttpResponse(gen_display(camera, op, screenparams),
                                                 content_type='multipart/x-mixed-replace; boundary=frame')
            return response
        except Exception:
            raise Http404


def getChatGptResponse(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode('utf-8'))
        res = requests.get(url='https://v1.apigpt.cn/',
                           params={"q": data['a']})
        answer = json.loads(res.text)
        print(answer)
        return JsonResponse({"data": {'data': answer['ChatGPT_Answer']}, "msg": answer['msg'], 'code': 2000})


def gen_display_camera(camera, screenparams={'screentype': 0, 'interval': 1, 'total': 100}):
    """
    视频流生成器功能。
    """
    c = 1
    r = 0
    if screenparams['screentype'] == 0:
        while camera.isOpened():
            ret, frame = camera.read()
            if (c % screenparams['interval'] == 0):
                if r == screenparams['total']:
                    # camera.flag = True
                    camera.release()
                    # camera.flag = False
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                # cv2.imwrite(path + str(c) + '.jpg', frame)
                if ret:
                    yield frame
            c += 1
    if screenparams['screentype'] == 1:
        while camera.isOpened():
            # 读取图片
            ret, frame = camera.read()
            FPS = camera.get(5)
            frameRate = int(FPS) * screenparams['interval']
            if (c % frameRate == 0):
                if (r == screenparams['total']):
                    camera.release()
                r += 1
                print("开始截取视频第：" + str(c) + " 帧")
                for o in op:
                    params = o['parameters']
                    print(params)
                    exec(o['content'])
                if ret:
                    # 转换为byte类型的，存储在迭代器中
                    yield frame
            c += 1
